home *** CD-ROM | disk | FTP | other *** search
/ MASPC 1 / MASPC_1.iso / Demos / Demo DIV / DATA / PRG / JUEGOS / BILLAR.PRG next >
Encoding:
Text File  |  1997-11-26  |  26.6 KB  |  752 lines

  1. //------------------------------------------------------------------------------
  2. //TITULO:      TOTAL BILLIARDS
  3. //AUTOR:       DANIEL NAVARRO
  4. //FECHA:       1/15/97
  5. //------------------------------------------------------------------------------
  6.  
  7. PROGRAM spanish_billar;
  8.  
  9. CONST
  10.     radio_bola=14;                      // Radio de la bola
  11.     x_reg_mesa=62-radio_bola;           // Region de la mesa
  12.     y_reg_mesa=104-radio_bola;
  13.     ancho_reg_mesa=580-62+radio_bola*2; // Region de la ventana
  14.     alto_reg_mesa=375-104+radio_bola*2;
  15.  
  16.     pos_toque_x=604;                    // Posicion de toque en efecto
  17.     pos_toque_y=452;
  18.  
  19. GLOBAL
  20.     puntuacion1;    // Numero de carambolas con la bola blanca
  21.     puntuacion2;    // Numero de carambolas con la bola amarilla
  22.  
  23.     blanco;         // Identificadores de las bolas
  24.     amarillo;
  25.     rojo;
  26.  
  27.     ultimo;         // Controla la ultima colision
  28.     quien;          // Identificador de la bola que colisiona
  29.     turno;          // Controla turno de los jugadores
  30.  
  31.     sonido0;        // Identificadores de sonido
  32.     sonido1;
  33.  
  34.     vtotal0;        // Velocidad total de la bola blanca
  35.     vtotal1;        // Velocidad total de la bola amarilla
  36.     modos[]="Apuntar","Efecto","Tiro";
  37.     txt_puntuacion[]="7 Puntos","21 Puntos","40 Puntos";
  38.     puntuacion=0;   // modos[] y txt_puntuacion[] texto que cambian
  39.     puntuaciones[]=7,21,40;
  40.     txt_modo;       // Identificador para txt_puntuacion[]
  41.     modo;           // Identificador de modo
  42.     id_efectos;     // Identificador de efectos
  43.     efecto_vert;    // Efecto vertical
  44.     efecto_horiz;   // Efecto horizontal
  45.     choque_contraria=0; // Comprueba el choque con la bola contraria
  46.     choque_roja=0;  // Comprueba el choque con la bola roja
  47. LOCAL
  48.     velocidad=0;    // Velocidad de bola
  49.     avelocidad=0;   // Velocidad acumulada
  50.     ang=0;          // Direccion
  51.  
  52.     x_resol;        // Coordenadas * 100
  53.     y_resol;
  54.  
  55.     incr_x;         // X incremento
  56.     incr_y;         // Y incremento
  57.  
  58. PRIVATE
  59.     ángulo2=0;      // Movimiento de la bola
  60.     inc_ángulo2=0;
  61.  
  62.     opción=0;       // Opción del menu
  63.     opciones[2];    // Identificador de texto
  64.     fin_juego=0;    // Bandera. 1=Fin ded juego
  65.     ultima_x;       // Ultimas posiciones del ratón
  66.     ultima_y;
  67. BEGIN
  68.     set_mode(m640x480);
  69.     set_fps(30,0);
  70.  
  71.     load_fpg("billar\billar.fpg");   // Carga graficos
  72.     load_fpg("billar\b_menu.fpg");
  73.  
  74.     load_fnt("billar\billar.fnt");   // Carga letras
  75.     load_fnt("billar\numeros.fnt");
  76.     load_fnt("billar\titulo.fnt");
  77.     load_fnt("billar\menu.fnt");
  78.  
  79.     sonido0=load_pcm("billar\billar0.pcm",0); // Carga sonidos
  80.     sonido1=load_pcm("billar\banda.pcm",0);
  81.  
  82.     // Crea una ventana
  83.     define_region(1,x_reg_mesa,y_reg_mesa,ancho_reg_mesa,alto_reg_mesa);
  84.  
  85.     LOOP
  86.         // Carga la paleta para que los gráficos salgan bien
  87.         load_pal("billar\b_menu.fpg");
  88.         put_screen(1,1);    // Pone la pantalla de fondo
  89.  
  90.         // Imprime mensajes
  91.         write(3,320,4,1,"TOTAL BILLIARD");
  92.         opciones[0]=write(4,400,320,0,"Empezar");
  93.         opciones[1]=write(4,400,354,0,txt_puntuacion[puntuacion]);
  94.         opciones[2]=write(4,400,388,0,"Salir al DOS");
  95.         write(4,320,480,7,"Daniel Navarro  DIV Games Studio");
  96.  
  97.         // Selecciona el gráfico del taco para el cursor
  98.         file=1;
  99.         graph=2;
  100.  
  101.         // Renicia las variables del cursor
  102.         y=342; incr_y=0; ángulo2=0;
  103.         opción=0;
  104.  
  105.         fade_on();  // Enciende la pantalla
  106.  
  107.         REPEAT  // Menu
  108.             ultima_y=mouse.y;   // Guarda la posición del ratón para mirar si hay cambio
  109.             x=17+get_distx(ang,16);
  110.             IF ((ang+=pi/8)>pi)
  111.                 ang-=2*pi;
  112.             END
  113.  
  114.             // Comprueba si se ha elegido una opción
  115.             IF (opción<>0 AND ang<pi/15 AND ang>-pi/15)
  116.                 incr_x=400;
  117.                 // Repite hasta que desaparezca el texto
  118.                 REPEAT
  119.                     move_text(opciones[opción-1],incr_x+=16,incr_y);
  120.                     FRAME;
  121.                 UNTIL (incr_x>640)  // Cambia texto
  122.                 // Se ha elegido la opcion de cambiar tipo de juego
  123.                 IF (opción==2)
  124.                     delete_text(opciones[1]);
  125.                     puntuacion=++puntuacion%3;
  126.                     opciones[1]=write(4,incr_x=640,incr_y,0,txt_puntuacion[puntuacion]);
  127.                     REPEAT
  128.                         move_text(opciones[1],incr_x-=16,incr_y);
  129.                         FRAME;
  130.                     UNTIL (incr_x==400)
  131.                     opción=0;
  132.                     incr_y=0;
  133.                 ELSE
  134.                     opción-=4;
  135.                 END
  136.             END
  137.             IF (incr_y==0)          // Cuando el palo este sobre una opción
  138.                 IF (key(_enter) OR mouse.left OR
  139.                     key(_control) OR key(_space))    // Selecciona esa opción
  140.                     incr_y=y-22;
  141.                     opción=(y-342)/34+1;
  142.                 ELSE
  143.                     IF ((key(_down) OR mouse.y>ultima_y) AND y<410)   // Cambia a otra opción
  144.                         incr_y=y+17;
  145.                         ángulo2=pi/2;
  146.                         inc_ángulo2=-pi/8;
  147.                     END
  148.                     IF ((key(_up) OR mouse.y<ultima_y)  AND y>342)     // Cambia a otra opción
  149.                         incr_y=y-17;
  150.                         ángulo2=-pi/2;
  151.                         inc_ángulo2=pi/8;
  152.                     END
  153.                 END
  154.             END
  155.  
  156.             IF (inc_ángulo2<>0)       // Detiene el incremento vertical
  157.                 ángulo2+=inc_ángulo2;
  158.                 y=incr_y+get_disty(ángulo2,17);
  159.                 IF (inc_ángulo2<0)
  160.                     IF (ángulo2<-pi/2)
  161.                         y=incr_y+17;
  162.                         incr_y=0;
  163.                         inc_ángulo2=0;
  164.                     END
  165.                 ELSE
  166.                     IF (ángulo2>pi/2)
  167.                         y=incr_y-17;
  168.                         incr_y=0;
  169.                         inc_ángulo2=0;
  170.                     END
  171.                 END
  172.             END
  173.             // comprueba la pulsacion de la tecla escape
  174.             IF (key(_esc))
  175.                 opción=-1;
  176.             END
  177.             FRAME;
  178.         UNTIL (opción<0)
  179.         // Borra todo y apaga la pantalla
  180.         fade_off();
  181.         clear_screen();
  182.         delete_text(all_text);
  183.         graph=0;
  184.         FRAME;
  185.  
  186.         IF (opción==-1)     // Sale del programa
  187.             exit("Gracias por jugar!!!",0);
  188.             FRAME;
  189.         END
  190.  
  191.         load_pal("billar\billar.fpg"); // Carga la paleta de colores
  192.  
  193.         // Imprime los textos necesarios
  194.         write(1,12,6,0,"Jugador 1");
  195.         write(1,628,6,2,"Jugador 2");
  196.         write_int(2,115,0,0,&puntuacion1);
  197.         write_int(2,525,0,2,&puntuacion2);
  198.  
  199.         // Pone los gráficos de la mesa y la bola de efectos
  200.         put(0,1,320,240);
  201.         put(0,8,pos_toque_x,pos_toque_y);
  202.  
  203.         // Crea el proceso que maneja los efectos
  204.         id_efectos=efecto();
  205.  
  206.         // Escribe el texto del turno
  207.         write(1,12,428,0,"Jugador");
  208.         write_int(1,98,428,0,&turno);
  209.         fade_on();
  210.  
  211.         // Crea las bolas
  212.         blanco=bola(3,320,240);
  213.         amarillo=bola(4,128,240-48);
  214.         rojo=bola(5,128,240+48);
  215.  
  216.  
  217.         // Valores iniciales
  218.         fin_juego=0;
  219.         choque_contraria=0;
  220.         choque_roja=0;
  221.         puntuacion1=0;
  222.         puntuacion2=0;
  223.         ultimo=0;
  224.         quien=0;
  225.         turno=2;
  226.  
  227.         REPEAT  // Bucle principal
  228.             // Comprueba que este parado todo y que no haya palo, es decir, el fin de la tirada
  229.             IF (blanco.velocidad==0 AND amarillo.velocidad==0 AND rojo.velocidad==0 AND NOT get_id(TYPE palo))
  230.                 // Si no ha chocado con las dos bolas a la vez,
  231.                 // es que no ha sido una carambola
  232.                 IF (NOT (choque_contraria AND choque_roja))
  233.                     // Cambia de turno
  234.                     IF (turno==1)
  235.                         turno=2;
  236.                     ELSE
  237.                         turno=1;
  238.                     END
  239.                 ELSE
  240.                     // Carambola conseguida
  241.                     IF (turno)  // Mira quien jugaba en ese turno
  242.                         // Mira los puntos obtenidos hasta ahora
  243.                         IF (++puntuacion1==puntuaciones[puntuacion])
  244.                             x=800;
  245.                             quien=write(1,x,240,4,"Jugador uno gana");
  246.                             FROM x=800 TO 319 STEP -8;
  247.                                 move_text(quien,x,240);
  248.                                 FRAME;
  249.                             END
  250.                             FROM x=0 TO 29;
  251.                                 FRAME;
  252.                             END
  253.                             fin_juego=1;
  254.                         END
  255.                     ELSE
  256.                         // Comprueba y hace lo mismo que antes pero para el otro jugador
  257.                         IF (++puntuacion2==puntuaciones[puntuacion])
  258.                             x=800;
  259.                             quien=write(1,x,240,4,"Jugador dos gana");
  260.                             FROM x=800 TO 320 STEP -8;
  261.                                 move_text(quien,x,240);
  262.                                 FRAME;
  263.                             END
  264.                             FROM x=0 TO 29;
  265.                                 FRAME;
  266.                             END
  267.                             fin_juego=1;
  268.                         END
  269.                     END
  270.                 END
  271.  
  272.                 // Comprueba si no ha acabado
  273.                 IF (NOT fin_juego)
  274.                     // Pone el palo dependiendo del turno al lado de la bola apropiada
  275.                     IF (turno)
  276.                         palo(blanco);
  277.                     ELSE
  278.                         palo(amarillo);
  279.                     END
  280.                     choque_contraria=0;
  281.                     choque_roja=0;
  282.                 END
  283.             END
  284.  
  285.             // Si se pulsa la tecla escape sale del juego
  286.             IF (key(_esc))
  287.                 fin_juego++;
  288.             END
  289.             FRAME;
  290.         UNTIL (fin_juego)
  291.  
  292.         fade_off();
  293.         signal(id,s_kill_tree);
  294.         signal(id,s_wakeup);
  295.         clear_screen();
  296.         delete_text(all_text);
  297.         FRAME;
  298.     END
  299. END
  300.  
  301. //------------------------------------------------------------------------------
  302. // Proceso bola
  303. // Maneja la bola
  304. //------------------------------------------------------------------------------
  305.  
  306. PROCESS bola(graph,x,y);
  307.  
  308. PRIVATE
  309.     id_colisiones;  // Identificador de colisiones
  310.     dir_final;      // Direccion despues de la colision
  311.  
  312.     veloc_final_x;  // Velocidad final despues de la colision
  313.     veloc_final_y;
  314.  
  315.     longitud;       // Longitud a un punto
  316.  
  317.     ultima_pos_x;   // Ultima posicion
  318.     ultima_pos_y;
  319.  
  320. BEGIN
  321.  
  322.     sombra(6);      // Pone la sombra de la bola
  323.  
  324.     x_resol=x*100;  // Coge las coordenadas multiplicadas por 100
  325.     y_resol=y*100;
  326.  
  327.     LOOP
  328.  
  329.         avelocidad+=velocidad;
  330.  
  331.         // Hasta que pare
  332.         WHILE (avelocidad>100)
  333.  
  334.             avelocidad-=100;        // A cada paso decrementa la velocidad
  335.  
  336.             ultima_pos_x=x_resol;   // Guarda posicion
  337.             ultima_pos_y=y_resol;
  338.  
  339.             // Mueve la bola
  340.             incr_x=get_distx(ang,100);
  341.             x_resol+=incr_x;
  342.             incr_y=get_disty(ang,100);
  343.             y_resol+=incr_y;
  344.  
  345.             // Comprueba el rebote con las bandas de manera vertical
  346.             IF ((y_resol<=10400 AND incr_y<0) OR (y_resol>=37400 AND incr_y>0))
  347.                 velocidad=velocidad*7/10;               // Reduce la velocidad
  348.                 sound(sonido1,80*velocidad/4000,100);   // Hace un sonido de rebote
  349.                 // Cambia el ángulo para que rebote
  350.                 ang=fget_angle(x,y,x+incr_x,y-incr_y)+efecto_horiz*(pi/96);
  351.                 // Quita cualquier efecto que existiera
  352.                 efecto_vert=80;
  353.                 efecto_horiz=0;
  354.             END
  355.  
  356.             // Comprueba el rebote con las bandas de manera horizontal
  357.             IF ((x_resol<=6200 AND incr_x<0) OR (x_resol>=57900 AND incr_x>0))
  358.                 velocidad=velocidad*7/10;
  359.                 sound(sonido1,30+50*velocidad/5000,100);
  360.                 ang=fget_angle(x,y,x-incr_x,y+incr_y)+efecto_horiz*(pi/96);
  361.                 efecto_vert=80;
  362.                 efecto_horiz=0;
  363.             END
  364.  
  365.             // Carga las coordenadas reales del gráfico con las temporales
  366.             x=x_resol/100;
  367.             y=y_resol/100;
  368.  
  369.             // Comprueba si ha chocado con una bola
  370.             IF (id_colisiones=collision(TYPE bola))
  371.                 // Mira si esta colision no esta mirada y no es con esta bola
  372.                 IF (ultimo<>id_colisiones+id OR quien<>id)
  373.                     // Guarda los identificadores para proximas comprobaciones
  374.                     quien=id;
  375.                     ultimo=id_colisiones+id;
  376.  
  377.                     // Comprueba si ha chocado la bola blanca con la amarilla
  378.                     IF (ultimo==blanco+amarillo)
  379.                         choque_contraria=TRUE;
  380.                     END
  381.  
  382.                     // Mira que bola tiene el turno
  383.                     IF (turno)
  384.                         // Y comprueba si choca con la roja
  385.                         IF (id_colisiones+id==blanco+rojo)
  386.                             choque_roja=TRUE;
  387.                         END
  388.                     ELSE
  389.                         IF (id_colisiones+id==amarillo+rojo)
  390.                             choque_roja=TRUE;
  391.                         END
  392.                     END
  393.  
  394.                     sound(sonido0,512,256); // Sonido de colision
  395.  
  396.                     avelocidad+=100;
  397.                     // Las bolas rebotan
  398.                     // Primero coge los incrementos horizontal y vertical de una bola
  399.                     incr_x=get_distx(ang,velocidad);
  400.                     incr_y=get_disty(ang,velocidad);
  401.  
  402.                     // Y los mismo incrementos de la otra
  403.                     id_colisiones.incr_x=get_distx(id_colisiones.ang,id_colisiones.velocidad);
  404.                     id_colisiones.incr_y=get_disty(id_colisiones.ang,id_colisiones.velocidad);
  405.  
  406.                     // Suma la velocidades, que es lo mismo que la fuerza total
  407.                     vtotal0=velocidad+id_colisiones.velocidad;
  408.  
  409.                     // Halla el angulo que hay entre las dos bolas que chocan
  410.                     dir_final=get_angle(id_colisiones)+efecto_horiz*(pi/96);
  411.  
  412.                     // Suma los incrementos sacando dos que es igual a la velocidades
  413.                     veloc_final_x=incr_x+id_colisiones.incr_x;
  414.                     veloc_final_y=incr_y+id_colisiones.incr_y;
  415.  
  416.                     // Halla la longitud del vector entre las dos bolas,
  417.                     // que es proporcional a la suma de las velocidades
  418.                     longitud=fget_dist(x,y,x+veloc_final_x,y+veloc_final_y)*efecto_vert/100;
  419.  
  420.                     // Borra los efectos una vez que han colisionado
  421.                     efecto_vert=80;
  422.                     efecto_horiz=0;
  423.  
  424.                     // A la bola que choca se le resta el vector
  425.                     // total del choque
  426.                     incr_x-=get_distx(dir_final,longitud);
  427.                     incr_y-=get_disty(dir_final,longitud);
  428.  
  429.                     // Y se hallan los nuevos valores para dicha bola
  430.                     ang=fget_angle(x,y,x+incr_x,y+incr_y);
  431.                     velocidad=fget_dist(x,y,x+incr_x,y+incr_y);
  432.  
  433.                     // A la bola que recibe el choque se le suma
  434.                     // el vector total que ha salido del choque
  435.                     id_colisiones.incr_x+=get_distx(dir_final,longitud);
  436.                     id_colisiones.incr_y+=get_disty(dir_final,longitud);
  437.  
  438.                     // Y se actualizan sus valores de ángulo y velocidad
  439.                     id_colisiones.ang=fget_angle(x,y,x+id_colisiones.incr_x,y+id_colisiones.incr_y);
  440.                     id_colisiones.velocidad=fget_dist(x,y,x+id_colisiones.incr_x,y+id_colisiones.incr_y);
  441.  
  442.                     // Por ultimo se hace una media con la fuerza inicial
  443.                     // para que en vez de ser proporcional, sea identica
  444.                     vtotal1=velocidad+id_colisiones.velocidad;
  445.                     velocidad=vtotal0*velocidad/vtotal1;
  446.                     id_colisiones.velocidad=vtotal0*id_colisiones.velocidad/vtotal1;
  447.  
  448.                     avelocidad=velocidad;
  449.                     id_colisiones.avelocidad=id_colisiones.velocidad;
  450.  
  451.                 END
  452.  
  453.                 x_resol=ultima_pos_x;     // Restaura posicion
  454.                 y_resol=ultima_pos_y;
  455.  
  456.             ELSE
  457.                 // Si el identificador es el de la propia bola
  458.                 // borra cualquier reseña del choque
  459.                 IF (quien==id)
  460.                     ultimo=0;
  461.                 END
  462.  
  463.             END
  464.  
  465.             FRAME(0);       // Refresca pantalla
  466.  
  467.         END
  468.  
  469.         x=x_resol/100;
  470.         y=y_resol/100;
  471.  
  472.         FRAME;
  473.         // Parando las bolas
  474.         IF (velocidad>10)
  475.             velocidad-=10;
  476.             IF (efecto_vert>80)
  477.                 efecto_vert-=2;
  478.                 velocidad+=(efecto_vert-80)/10;
  479.             END
  480.             IF (efecto_vert<80)
  481.                 efecto_vert++;
  482.                 velocidad-=(80-efecto_vert)/2;
  483.             END
  484.         ELSE
  485.             // Se ha parado completamente
  486.             velocidad=0;
  487.         END
  488.  
  489.     END
  490. END
  491.  
  492. //------------------------------------------------------------------------------
  493. // Proceso sombra
  494. // Muestra las sombras de la bola y el palo
  495. //------------------------------------------------------------------------------
  496.  
  497. PROCESS sombra(graph);
  498.  
  499. BEGIN
  500.     region=1;               // Elige la región
  501.     z=1;                    // Lo pone por debajo de las bolas
  502.     flags=4;                // Lo pone transparente
  503.     priority=-1;            // Hace que se ejecute despues de la bola
  504.     LOOP
  505.         angle=father.angle; // Coge el angulo del padre
  506.         x=father.x+8;       // Sigue al proceso que lo llamo
  507.         y=father.y+8;       // el palo o la bola
  508.         FRAME;
  509.     END
  510. END
  511.  
  512. //------------------------------------------------------------------------------
  513. // Proceso palo
  514. // Controla el palo
  515. //------------------------------------------------------------------------------
  516. PROCESS palo(idbola);
  517.  
  518. PRIVATE
  519.     ultima_pos_ratón;   // Ultima posicion del raton
  520.     real_x_ratón;       // Coordenadas reales del raton
  521.     real_y_ratón;
  522.     fuerza;             // Fuerza de lanzamiento
  523.     distancia;          // Para coger la distancia
  524.     ángulo_res;         // Para coger el angulo
  525.  
  526. BEGIN
  527.     sombra(7);      // Crea la sombra del palo
  528.  
  529.     // Imprime el modo de juego
  530.     txt_modo=write(1,114,428,0,modos[modo=0]);
  531.  
  532.     mouse.x=320;    // Centra el raton
  533.     mouse.y=240;
  534.     graph=2;        // Elige el gráfico del palo
  535.     ultima_pos_ratón=mouse.x;
  536.     // Coge las coordenadas respecto a la bola que señala
  537.     x=idbola.x;
  538.     y=idbola.y;
  539.     angle=-pi/2;    // Angulo inicial
  540.     // Posicion inicial de los efectos
  541.     id_efectos.x=pos_toque_x;
  542.     id_efectos.y=pos_toque_y;
  543.  
  544.     LOOP
  545.         // Esta en el modo de apuntar con el taco
  546.         IF (modo==0)
  547.             // Actualiza la posición del taco con la del ratón
  548.             angle-=(ultima_pos_ratón-mouse.x)*(pi/256);
  549.             ultima_pos_ratón=mouse.x;
  550.             // Hace que el raton este entre 512 y 512
  551.             IF (mouse.x<128)
  552.                 mouse.x+=320;
  553.                 ultima_pos_ratón=mouse.x;
  554.             END
  555.             IF (mouse.x>512)
  556.                 mouse.x-=320;
  557.                 ultima_pos_ratón=mouse.x;
  558.             END
  559.             // Comprueba si se ha pulsado el botón del ratón
  560.             IF (mouse.left)
  561.                 // Borra el texto antiguo y pone el nuevo
  562.                 delete_text(txt_modo);
  563.                 txt_modo=write(1,114,428,0,modos[1]);
  564.                 // Centra el ratón
  565.                 mouse.x=320;
  566.                 mouse.y=240;
  567.                 // Espera a que se suelte el botón del ratón
  568.                 REPEAT
  569.                     FRAME;
  570.                 UNTIL (NOT mouse.left)
  571.                 // Cambia el modo de tratar el taco
  572.                 modo=1;
  573.                 // Coge las coordenadas del ratón y las guarda en variables propias
  574.                 real_x_ratón=mouse.x;
  575.                 real_y_ratón=mouse.y;
  576.             ELSE
  577.                 // Si no se pulsa el ratón crea el visor
  578.                 visor(idbola,angle+pi);
  579.             END
  580.         END
  581.         // Modo en el que se selecciona efecto
  582.         IF (modo==1)
  583.  
  584.             // Actualiza el afecto dependiendo de las coordenadas del ratón
  585.             id_efectos.x=pos_toque_x+(mouse.x-real_x_ratón)/3;
  586.             id_efectos.y=pos_toque_y+(mouse.y-real_y_ratón)/3;
  587.  
  588.             // Coge la distancia del centro de la bola a la posición del efecto
  589.             distancia=fget_dist(pos_toque_x,pos_toque_y,id_efectos.x,id_efectos.y);
  590.  
  591.             // Si la longitud es mayor que 22 la trunca para hacerlo redondo
  592.             IF (distancia>22)
  593.                 ángulo_res=fget_angle(pos_toque_x,pos_toque_y,id_efectos.x,id_efectos.y);
  594.                 id_efectos.x=pos_toque_x+get_distx(ángulo_res,22);
  595.                 id_efectos.y=pos_toque_y+get_disty(ángulo_res,22);
  596.             END
  597.  
  598.             // Mira si se pulsa el botón del ratón
  599.             IF (mouse.left)
  600.  
  601.                 // Borra el texto antiguo
  602.                 delete_text(txt_modo);
  603.  
  604.                 // Pone el texto nuevo
  605.                 txt_modo=write(1,114,428,0,modos[2]);
  606.  
  607.                 // Centra el ratón
  608.                 mouse.x=320;
  609.                 mouse.y=240;
  610.  
  611.                 // Espera a que se suelte el botón del ratón
  612.                 REPEAT
  613.                     FRAME;
  614.                 UNTIL (NOT mouse.left)
  615.                 // Actualiza las variables del proceso
  616.                 ultima_pos_ratón=mouse.y;
  617.                 real_x_ratón=x;
  618.                 real_y_ratón=y;
  619.                 // Cambia el modo de acción del taco
  620.                 modo=2;
  621.                 // Guarda los efectos elegidos en sus variables
  622.                 efecto_vert=id_efectos.y-pos_toque_y;
  623.                 IF (efecto_vert<0)
  624.                     efecto_vert=80-28*-efecto_vert/22;
  625.                 ELSE
  626.                     efecto_vert=80+efecto_vert*120/22;
  627.                 END
  628.                 efecto_horiz=id_efectos.x-pos_toque_x;
  629.             END
  630.         END
  631.         // Modo de taco de seleccion de fuerza
  632.         IF (modo==2)
  633.             // Coloca el taco en relación a las coordenadas del ratón
  634.             x=real_x_ratón+get_distx(angle,mouse.y-240);
  635.             y=real_y_ratón+get_disty(angle,mouse.y-240);
  636.             // Si se pasa de un limite significa que se ha hecho el tiro
  637.             IF (mouse.y<232)
  638.                 // Borra el texto de modo
  639.                 delete_text(txt_modo);
  640.                 // Hace un sonido
  641.                 sound(sonido1,100,128);
  642.                 // Halla la fuerza, dependiendo de la última posición del ratón
  643.                 fuerza=(ultima_pos_ratón-mouse.y)*100;
  644.                 // Comprueba si la fuerza se pasa de los limites permitidos
  645.                 IF (fuerza<200)
  646.                     fuerza=200;
  647.                 END
  648.                 IF (fuerza>8000)
  649.                     fuerza=8000;
  650.                 END
  651.                 // Guarda la fuerza como velocidad de la bola
  652.                 idbola.velocidad=fuerza;
  653.                 // Y pone el ángulo apropiado a la bola
  654.                 idbola.ang=angle+pi;
  655.                 // Borra todo y se prepara para salir del proceso
  656.                 ultimo=0;
  657.                 signal(id,s_kill);
  658.                 signal(son,s_kill);
  659.             END
  660.             // Comprueba si se pulsa el botón del ratón
  661.             IF (mouse.left)
  662.                 // Borra el texto antiguo y pone el nuevo
  663.                 delete_text(txt_modo);
  664.                 txt_modo=write(1,112,428,0,modos[0]);
  665.                 // Actualiza la posición del taco al lado de la bola
  666.                 x=idbola.x;
  667.                 y=idbola.y;
  668.                 // Centra el ratón
  669.                 mouse.x=320;
  670.                 mouse.y=240;
  671.                 // Espera hasta que se suelte el botón del ratón
  672.                 REPEAT
  673.                     FRAME;
  674.                 UNTIL (NOT mouse.left)
  675.                 // Cambia de modo
  676.                 ultima_pos_ratón=mouse.x;
  677.                 modo=0;
  678.             ELSE
  679.                 // Actualiza la última posición del ratón
  680.                 ultima_pos_ratón=mouse.y;
  681.             END
  682.         END
  683.         FRAME;
  684.     END
  685. END
  686.  
  687. //------------------------------------------------------------------------------
  688. // Proceso visor
  689. // Muestra donde ira la bola
  690. //------------------------------------------------------------------------------
  691.  
  692. PROCESS visor(idbola,ang);
  693.  
  694. PRIVATE
  695.     impacto=0;        // Bandera. 1=impacto 0=no impacto
  696.     id_bola2;         // Identificador de la bola
  697.  
  698. BEGIN
  699.     z=2;
  700.     // Inicialmente coge el gráfico de la bola para comprobar colisiones
  701.     graph=idbola.graph;
  702.     // También coge las coordenadas de la bola que es lanzada
  703.     x_resol=idbola.x_resol;
  704.     y_resol=idbola.y_resol;
  705.     REPEAT
  706.  
  707.         // Mueve el visor un punto en el ángulo deseado
  708.         incr_x=get_distx(ang,100);
  709.         x_resol+=incr_x;
  710.         incr_y=get_disty(ang,100);
  711.         y_resol+=incr_y;
  712.  
  713.         // La coloca en la nueva posición
  714.         x=x_resol/100;
  715.         y=y_resol/100;
  716.  
  717.         // Testea limites de la mesa
  718.         IF ((y_resol<=10400 AND incr_y<0) OR (y_resol>=37400 AND incr_y>0) OR (x_resol<=6200 AND incr_x<0) OR (x_resol>=57900 AND incr_x>0))
  719.             impacto=1;
  720.         END
  721.  
  722.         // Va comprobando si colisiona con cualquiera otra bola
  723.         WHILE (id_bola2=collision(TYPE bola))
  724.             IF (id_bola2<>idbola)
  725.                 impacto=1;
  726.             END
  727.         END
  728.         FRAME(0);   // Hace que no aparezca en pantalla
  729.     UNTIL (impacto) // Busca la posicion del visor hasta que colisiones
  730.     graph=9;        // Selecciona ya el gráfico propio del visor
  731.     FRAME;          // Ahora ya puede mostrar el gráfico del visor
  732. END
  733.  
  734. //------------------------------------------------------------------------------
  735. // Proceso efecto
  736. // Muestra la posicion del toque
  737. //------------------------------------------------------------------------------
  738.  
  739. PROCESS efecto();
  740.  
  741. BEGIN
  742.     // Coge las coordenadas de la posición de toque
  743.     x=pos_toque_x;
  744.     y=pos_toque_y;
  745.     graph=6;        // Selecciona el gráfico
  746.     size=29;        // Y cambia el tamaño porque es muy grande
  747.     LOOP
  748.         FRAME;
  749.     END
  750. END
  751.  
  752.